package simulador;

import java.util.ArrayList;
import java.util.List;

import eduni.simjava.Sim_entity;
import eduni.simjava.Sim_event;
import eduni.simjava.Sim_port;
import eduni.simjava.Sim_stat;
import eduni.simjava.Sim_system;
import eduni.simjava.distributions.Sim_negexp_obj;


public class Locadora extends Sim_entity{

	private Sim_port entrada;
	private List<Sim_port> saidas;
	private Sim_stat stat;
	private Sim_negexp_obj delay;
	final static String PORTA_DE_ENTRADA = "Locadora.in";
	final static String PREFIXO_DE_PORTA_DE_SAIDA = "Locadora.out.";
	final static String NOME_DA_ENTIDADE = "Locadora";
	final static String STAT_CLIENTES_ATENDIDOS = "Clientes atendidos";
	final static String STAT_SAIDAS_SEM_CARRO = "Saidas sem carro";
	final static String STAT_ALUGUEIS_DE_CARRO = "Alugueis de carro";

	public Locadora(int numeroDeCarros, double tempoDeAtendimento) {
		super(NOME_DA_ENTIDADE);
		
		
	    delay = new Sim_negexp_obj("Delay", tempoDeAtendimento);
	    add_generator(delay);
		
		entrada = new Sim_port(Locadora.PORTA_DE_ENTRADA);
		add_port(entrada);
		
		saidas = new ArrayList<Sim_port>();
		for (int i = 0; i < numeroDeCarros; i++) {
			Sim_port port = new Sim_port(PREFIXO_DE_PORTA_DE_SAIDA + i);
			saidas.add(port);
			add_port(port);
		}
		
		stat = new Sim_stat();
		stat.add_measure(STAT_CLIENTES_ATENDIDOS, Sim_stat.RATE_BASED);
		stat.add_measure(STAT_SAIDAS_SEM_CARRO, Sim_stat.RATE_BASED);
		stat.add_measure(STAT_ALUGUEIS_DE_CARRO, Sim_stat.RATE_BASED);
		stat.add_measure(Sim_stat.ARRIVAL_RATE);
		stat.add_measure(Sim_stat.UTILISATION);
		stat.add_measure(Sim_stat.SERVICE_TIME);
		stat.add_measure(Sim_stat.WAITING_TIME);
		stat.add_measure(Sim_stat.QUEUE_LENGTH);
		stat.add_measure(Sim_stat.THROUGHPUT);
		set_stat(stat);
	}

	public void body() {
		while (Sim_system.running()) {
			Sim_event e = new Sim_event();
			sim_get_next(e);
			sim_process(delay.sample());
			sim_completed(e);
			stat.update(STAT_CLIENTES_ATENDIDOS, Sim_system.sim_clock());
			
			//TODO gambiarra
			boolean temCarro = false;
			for (Sim_port porta : saidas) {
				Carro carro = (Carro) Sim_system.get_entity(porta.get_dest());
				if(!carro.isOcupado()){
					sim_schedule(porta, 0.0, 1);
					temCarro = true;
					stat.update(STAT_ALUGUEIS_DE_CARRO, Sim_system.sim_clock());
					break;
				}
			}
			
			if(!temCarro){
				stat.update(STAT_SAIDAS_SEM_CARRO, Sim_system.sim_clock());
				sim_trace(1, "Cliente foi embora sem carro.");				
			}
		}
	}	
	
}
